using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using extend_360.dto;
using Microsoft.Win32;

namespace extend_360.utils
{
    public class ActionUtils
    {
        /// <summary>
        /// 搜索词目录
        /// </summary>
        static string SearchWordPath = SystemUtils.GetDomainPath() + "/config/search";

        /// <summary>
        /// 安装目录
        /// </summary>
        static string InstallPackPath = SystemUtils.GetDomainPath() + "/config/package";

        /// <summary>
        /// 安装目录注册表数据
        /// </summary>
        static string RegistryPath = @"SOFTWARE\John\Install";

        /**
         * 浏览器行为
         */
        public static void OpenBrowser(string displayLocation, Config.SoftInfo item)
        {
            SystemUtils.ConsoleWrite("打开浏览器===开始", ConsoleColor.Green);
            //string cmd = $"/c start https://hao.360.com/?src=lm&ls=n627919d4a2&wd={FileUtils.ReadFile(SearchWordPath)}";
            // CmdUtils.Process(cmd, 10000);
            Process process = null;

            try
            {
                process = Process.Start(displayLocation,
                    $"https://hao.360.com/?src=lm&ls=n627919d4a2&wd={FileUtils.ReadFile(SearchWordPath)}");
                Thread.Sleep(15000);
                SystemUtils.ConsoleWrite("打开浏览器===完成", ConsoleColor.Green);

                // 获取浏览器窗口的位置和大小
                IntPtr hwnd = WindowsAPIUtils.GetForegroundWindow();
                WindowsAPIUtils.GetWindowRect(hwnd, out WindowsAPIUtils.RECT windowRect);

                Config.Point axis = RandomCoordinateAxis(item.PointGroup);
                WindowsAPIUtils.SetCursorPos(axis.X, axis.Y);

                // 模拟键盘输入搜索关键字
                WindowsAPIUtils.KeyDown(0x0D); // 回车键的虚拟键码
                //KeyUp(0x0D);
                // 等待搜索结果加载
                Thread.Sleep(3000);

                Random random = new Random();

                // 模拟滚动页面
                int count = random.Next(5, 20);
                SystemUtils.ConsoleWrite("随机滚动页面===次数开始" + count, ConsoleColor.Green);
                for (int i = 0, j = count; i < j; i++) // 向下滚动 10 次
                {
                    WindowsAPIUtils.MouseScroll(-120); // 向下滚动
                    Thread.Sleep(500); // 每次滚动间隔 500 毫秒
                }

                switch (random.Next(0, 2))
                {
                    case 0: // 搜索
                        SystemUtils.ConsoleWrite("随机滚动页面==次数完成", ConsoleColor.Green);
                        break;
                    case 1: // 点击
                        SystemUtils.ConsoleWrite("点击页面超链接===开始", ConsoleColor.Green);
                        // 计算浏览器窗口内的随机坐标
                        string originalAddress = WindowsAPIUtils.GetCurrentWindowTitle();

                        string currentAddress = "";
                        do
                        {
                            int x = random.Next(windowRect.Left + 50,
                                windowRect.Right - 50); // 避开边缘
                            int y = random.Next(windowRect.Top + 50, windowRect.Bottom - 50);
                            // 模拟鼠标移动到随机位置并点击
                            WindowsAPIUtils.SetCursorPos(x, y);
                            Thread.Sleep(500); // 等待鼠标移动完成
                            WindowsAPIUtils.MouseClick();
                            Thread.Sleep(2000); // 每次点击间隔 2 秒
                            currentAddress = WindowsAPIUtils.GetCurrentWindowTitle();

                            // SystemUtils.ConsoleWrite(currentAddress, ConsoleColor.Yellow);
                        } while (originalAddress.Equals(currentAddress,
                                     StringComparison.CurrentCultureIgnoreCase));

                        SystemUtils.ConsoleWrite("点击页面超链接===完成", ConsoleColor.Green);
                        break;
                }
            }
            catch
            {
            }
            finally
            {
                try
                {
                    CmdUtils.KillProcessByApplicationName(displayLocation);
                }
                catch (Exception e)
                {
                }
            }
        }

        /// <summary>
        /// 安装软件
        /// </summary>
        /// <param name="config"></param>
        /// <param name="ratio">当前系统的分辨率</param>
        public static void InstallPackage(Config config, string ratio)
        {
            if (config?.SoftConfig == null || config.SoftConfig.Count == 0)
            {
                SystemUtils.ConsoleWrite("Install === 无可用安装包配置", ConsoleColor.Red);
                return;
            }

            string[] directorys = Directory.GetDirectories(InstallPackPath);
            if (directorys == null || directorys.Length == 0)
            {
                SystemUtils.ConsoleWrite($"Install === 安装包路径下没有文件夹,{InstallPackPath}",
                    ConsoleColor.Red);
                return;
            }

            SystemUtils.ConsoleWrite($"Install === 随机获取文件夹安装软件", ConsoleColor.Green);
            Random random = new Random();
            string installPath = directorys[random.Next(0, directorys.Length)];

            installPath =
                RegistryKeyUtils.GetRegistryValue(RegistryPath, "InstallPath", installPath);

            List<string> files = FileUtils.GetFiles(installPath);
            if (files == null || files.Count == 0)
            {
                SystemUtils.ConsoleWrite($"Install === 安装包路径下没有文件,{installPath}", ConsoleColor.Red);
                return;
            }

            List<FileInfoDto> fileInfoDtos = FileUtils.GetFileInfo(files);
            // 随机安装数量
            List<Config.SoftInfo> softInfoDataOrgs = new List<Config.SoftInfo>();
            int needInstallNum = random.Next(0, config.SoftConfig.Count());
            for (int i = 0; i < needInstallNum; i++)
            {
                softInfoDataOrgs.Add(config.SoftConfig[random.Next(0, config.SoftConfig.Count)]);
            }

            softInfoDataOrgs = softInfoDataOrgs.Distinct().ToList();


            /**
             * 1、随机找到安装目录 安装软件
             */
            List<Tuple<FileInfoDto, Config.SoftInfo>> needInstalls =
                new List<Tuple<FileInfoDto, Config.SoftInfo>>();
            List<Tuple<FileInfoDto, Config.SoftInfo>> needOpens =
                new List<Tuple<FileInfoDto, Config.SoftInfo>>();
            foreach (var item in softInfoDataOrgs)
            {
                FileInfoDto fileInfoDto = fileInfoDtos.Find(x =>
                    x.FileName.Contains(item.PackageName,
                        StringComparison.CurrentCultureIgnoreCase) &&
                    !string.IsNullOrEmpty(item.PackageName));
                if (fileInfoDto == null)
                {
                    SystemUtils.ConsoleWrite($"Install === 安装{item.Name}失败，安装包不存在",
                        ConsoleColor.Yellow);
                    continue;
                }

                if (!CheckedPackageInstalled(item.Name))
                {
                    needInstalls.Add(new Tuple<FileInfoDto, Config.SoftInfo>(fileInfoDto, item));
                }

                needOpens.Add(new Tuple<FileInfoDto, Config.SoftInfo>(fileInfoDto, item));
            }


            if (needInstalls.Count > 0)
            {
                // 关闭360安全卫士
                if (CheckedPackageInstalled("360安全卫士"))

                {
                    try
                    {
                        Process[] processes = Process.GetProcessesByName("360Safe");
                        WindowsAPIUtils.KillProcess(processes);
                        processes = Process.GetProcessesByName("360Tray");
                        WindowsAPIUtils.KillProcess(processes);
                    }
                    catch (Exception e)
                    {
                        SystemUtils.ConsoleWrite("关闭360安全卫士异常" + e.Message, ConsoleColor.Red);
                    }
                }
            }

            Config.Security360 security360 = config?.Check360Security.FirstOrDefault(x =>
                x.Ratio.Trim().Equals(ratio.Trim()));
            foreach (var item in needInstalls)
            {
                // 开始安装
                InstallPackage(item.Item1, item.Item2, security360);
            }

            // 需要打开操作
            foreach (var item in needOpens)
            {
                OpenSoft(item.Item1, item.Item2, security360);
            }


            //OpenSoft(null, needOpens[0].Item2,config);
            // 关机
            CmdUtils.ShutDown();
        }

        static void InstallPackage(FileInfoDto fileInfoDto, Config.SoftInfo item,
            Config.Security360 security360)
        {
            SystemUtils.ConsoleWrite($"Install === 正在安装{item.Name}", ConsoleColor.Green);
            Process process = new Process();
            process.StartInfo.FileName = fileInfoDto.FilePath;
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.Arguments = item.InstallParams;
            process.StartInfo.Verb = "runas"; // 管理员权限运行
            try
            {
                Check360Security(security360);
                process.Start();
                // 等待安装完成
                process.WaitForExit();
                SystemUtils.ConsoleWrite($"Install === 安装{item.Name}成功", ConsoleColor.Green);
            }
            catch (Exception ex)
            {
                SystemUtils.ConsoleWrite($"Install === 安装{item.Name}过程中发生错误,{ex.Message}",
                    ConsoleColor.Green);
            }
        }


        /// <summary>
        /// 获取随机坐标轴
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        static Config.Point RandomCoordinateAxis(List<Config.Point> item)
        {
            Random random = new Random();
            int x = random.Next(0, item.Count);
            SystemUtils.ConsoleWrite("随机数" + x, ConsoleColor.Yellow);
            return item[x];
        }

        static void Click(Config.Point axis, int sleepTime = 3000)
        {
            SystemUtils.ConsoleWrite("鼠标坐标X:" + axis.X + ",Y:" + axis.Y, ConsoleColor.DarkBlue);
            WindowsAPIUtils.SetCursorPos(axis.X, axis.Y);
            WindowsAPIUtils.MouseClick(); //
            Thread.Sleep(sleepTime);
            WindowsAPIUtils.KeyDown(0x0D); // 防止有弹层
        }

        /// <summary>
        /// 打开软件信息
        /// </summary>
        /// <param name="fileInfoDto"></param>
        /// <param name="item"></param>
        /// <param name="security360">当前系统的分辨率</param>
        static void OpenSoft(FileInfoDto fileInfoDto, Config.SoftInfo item,
            Config.Security360 security360)
        {
            // 获取软件安装路径
            string displayLocation =
                RegistryKeyUtils.GetRegistryValue(Registry.CurrentUser, "DisplayIcon", item.Name)
                    .Item2;
            if (string.IsNullOrEmpty(displayLocation))
            {
                displayLocation = RegistryKeyUtils
                    .GetRegistryValue(Registry.LocalMachine, "DisplayIcon", item.Name)
                    .Item2;
            }

            if (string.IsNullOrEmpty(displayLocation))
            {
                SystemUtils.ConsoleWrite($"OpenSoft === 软件{item.Name}的安装路径获取失败,无法打开",
                    ConsoleColor.Red);
                return;
            }

            SystemUtils.ConsoleWrite($"OpenSoft === 正在打开{item.Name}", ConsoleColor.DarkGreen);
            Check360Security(security360);
            switch (item.Type)
            {
                case 1:
                    OpenBrowser(displayLocation, item);
                    break;
                default:
                    SoftWare(displayLocation, item);
                    break;
            }
        }

        private static void SoftWare(string displayLocation, Config.SoftInfo item)
        {
            Process process = CmdUtils.ProcessByPath(displayLocation, 30000);
            try
            {
                IntPtr? hWnd = process?.MainWindowHandle;
                if (hWnd == null || hWnd.Value == IntPtr.Zero)
                {
                    SystemUtils.ConsoleWrite($"OpenSoft === 正在打开{item.Name}失败,疑似未加载，重新获取句柄",
                        ConsoleColor.Red);
                    hWnd = WindowsAPIUtils.FindWindowByTitle(null, item.WindowName);
                    if (hWnd.Value == IntPtr.Zero)
                    {
                        SystemUtils.ConsoleWrite($"OpenSoft === 重新打开{item.Name}失败,疑似未加载",
                            ConsoleColor.Red);
                        return;
                    }

                    SystemUtils.ConsoleWrite($"OpenSoft === 重新获取句柄{item.Name}成功",
                        ConsoleColor.Green);
                }

                if (hWnd.Value != IntPtr.Zero)
                {
                    WindowsAPIUtils.SetForegroundWindow(hWnd.Value);
                }

                //设置窗体位置
                WindowsAPIUtils.SetWindowPos(hWnd.Value, 0, 0);
                /*if (item.Type == 2)
                {
                    // 开启的是360安全卫士 开启开发者目录与自我保护
                    Close360SafeSet();
                }*/

                Config.Point axis = RandomCoordinateAxis(item.PointGroup);

                #region 多次点击

                Click(axis);
                if (axis.PointGroup != null)
                {
                    axis = RandomCoordinateAxis(axis.PointGroup);
                    Click(axis);
                }

                #endregion

                //KeyUp(0x0D);
                // 等待搜索结果加载

                Random random = new Random();

                // 模拟滚动页面
                int count = random.Next(5, 25);
                SystemUtils.ConsoleWrite("随机滚动页面===次数开始" + count, ConsoleColor.Green);
                for (int i = 0, j = count; i < j; i++) // 向下滚动 10 次
                {
                    WindowsAPIUtils.MouseScroll(-120); // 向下滚动
                    Thread.Sleep(500); // 每次滚动间隔 500 毫秒
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                try
                {
                    CmdUtils.KillProcessByApplicationName(displayLocation);
                }
                catch (Exception e)
                {
                }
            }
        }

        /// <summary>
        /// 关闭360安全卫士
        /// </summary>
        private static void Close360SafeSet()
        {
            int sleepTime = 1500;
            Config.Point axis = new Config.Point() { X = 845, Y = 20 }; //设置
            SystemUtils.ConsoleWrite("360设置中心===设置", ConsoleColor.Green);
            Click(axis, sleepTime);
            axis = new Config.Point() { X = 880, Y = 50 }; //选择设置
            SystemUtils.ConsoleWrite("360设置中心===选择设置", ConsoleColor.Green);
            Click(axis, sleepTime);
            // 获取设置窗体句柄
            IntPtr hWnd = WindowsAPIUtils.FindWindowByTitle(null, "360设置中心");
            SystemUtils.ConsoleWrite("360设置中心===获取设置窗体句柄", ConsoleColor.Green);
            if (hWnd == IntPtr.Zero)
            {
                SystemUtils.ConsoleWrite("360设置中心===获取窗体句柄失败", ConsoleColor.Red);
                return;
            }

            WindowsAPIUtils.SetForegroundWindow(hWnd);
            //设置窗体位置
            WindowsAPIUtils.SetWindowPos(hWnd, 0, 0);
            axis = new Config.Point() { X = 70, Y = 90 }; // 基本设置
            Click(axis, sleepTime);
            SystemUtils.ConsoleWrite("360设置中心===基本设置", ConsoleColor.Green);
            // 滚动到最后
            WindowsAPIUtils.MouseScroll(-600); // 向下滚动
            Thread.Sleep(1000);
            axis = new Config.Point() { X = 85, Y = 325 }; // 安全防护中心
            Click(axis, sleepTime);
            SystemUtils.ConsoleWrite("360设置中心===安全防护中心", ConsoleColor.Green);
            WindowsAPIUtils.MouseScroll(-600); // 向下滚动
            Thread.Sleep(1000);
            axis = new Config.Point() { X = 90, Y = 250 }; // 点击开发者模式
            Click(axis, sleepTime);
            SystemUtils.ConsoleWrite("360设置中心===点击开发者模式", ConsoleColor.Green);
            axis = new Config.Point() { X = 232, Y = 202 }; // 点击开发者模式-关闭360自我保护
            Click(axis, sleepTime);

            // 获取设置窗体句柄
            hWnd = WindowsAPIUtils.FindWindowByTitle(null, "360产品");
            SystemUtils.ConsoleWrite("360产品===获取设置窗体句柄", ConsoleColor.Green);
            if (hWnd == IntPtr.Zero)
            {
                SystemUtils.ConsoleWrite("360产品===获取窗体句柄失败", ConsoleColor.Red);
                return;
            }

            WindowsAPIUtils.SetForegroundWindow(hWnd);
            //设置窗体位置
            WindowsAPIUtils.SetWindowPos(hWnd, 0, 0);
            axis = new Config.Point() { X = 140, Y = 95 }; // 点击开发者模式-关闭360自我保护-确定
            Click(axis, sleepTime);

            SystemUtils.ConsoleWrite("360设置中心===主动防御", ConsoleColor.Green);
            axis = new Config.Point() { X = 232, Y = 437 }; // 点击开发者模式-主动防御
            Click(axis, sleepTime);
            axis = new Config.Point() { X = 420, Y = 295 }; // 点击开发者模式-主动防御--确认
            Click(axis, sleepTime);

            axis = new Config.Point() { X = 720, Y = 485 }; // 点击开发者模式-主动防御--保存
            Click(axis, sleepTime);
        }

        /// <summary>
        /// 360安全拦截检查点击允许
        /// </summary>
        static void Check360Security(Config.Security360 check360Security)
        {
            Task.Run(() =>
            {
                Task.Delay(8000).Wait();
                if (check360Security?.PointGroup != null)
                {
                    SystemUtils.ConsoleWrite("360拦截允许操作===允许操作", ConsoleColor.Green);
                    foreach (var item in check360Security.PointGroup)
                    {
                        Click(item); // 360拦截允许操作
                    }
                }

                if (check360Security?.PointGroup2 != null)
                {
                    SystemUtils.ConsoleWrite("360拦截允许操作===允许本次操作", ConsoleColor.Green);
                    foreach (var item in check360Security.PointGroup2)
                    {
                        Click(item); // 360拦截允许操作
                    }
                }
            });
        }

        /// <summary>
        /// 检查软件是否安装
        /// </summary>
        /// <param name="softwareName">包名称</param>
        static bool CheckedPackageInstalled(string softwareName)
        {
            SystemUtils.ConsoleWrite($"CheckedPackageInstalled ===  开始检查软件{softwareName}是否安装",
                ConsoleColor.Green);
            return RegistryKeyUtils
                       .GetRegistryValue(Registry.CurrentUser, "DisplayName", softwareName).Item1
                   || RegistryKeyUtils
                       .GetRegistryValue(Registry.LocalMachine, "DisplayName", softwareName).Item1;
        }
    }
}